package com.culture.bootdemo.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.culture.bootdemo.common.basevo.Result;
import com.culture.bootdemo.handler.handler1.ExcelHeadValidHandler;
import com.culture.bootdemo.model.enums.ExcelEnum;
import com.culture.bootdemo.model.vo.ExcelReadVO;
import com.culture.bootdemo.model.vo.ReadData;
import com.culture.bootdemo.model.vo.Write2Data;
import com.culture.bootdemo.model.vo.WriteData;
import com.culture.bootdemo.service.UploadService;
import com.culture.bootdemo.utils.fileutils.EasyExcelFiledUtil;
import com.culture.bootdemo.utils.fileutils.EasyExcelUtil;
import com.culture.bootdemo.utils.fileutils.EasyExcelUtil2;
import com.culture.bootdemo.utils.fileutils.UploadDataListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author wen
 * @date 2019/11/15 13:47
 * @Description
 **/
@RestController
@RequestMapping("/excel")
public class ExcelController {

    private static final String LOAD_PATH = "/data/write/";
    @Autowired
    private UploadService uploadService;

    @GetMapping("writeTest1")
    public Result writeTest1() {
        List<WriteData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WriteData data = new WriteData(i, new Date(), 2, "");
            list.add(data);
        }

        File dfile = new File(LOAD_PATH);
        if (!dfile.exists()) {
            dfile.mkdirs();
        }
        // 写法1
        String fileName = LOAD_PATH + System.currentTimeMillis() + ".xlsx";
        // 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭
        // 如果这里想使用03 则 传入excelType参数即可
        EasyExcel.write(fileName, WriteData.class).sheet("模板").doWrite(list);

       /* // 写法2
        fileName = LOAD_PATH + System.currentTimeMillis() + ".xlsx";
        // 这里 需要指定写用哪个class去写
        ExcelWriter excelWriter = EasyExcel.write(fileName, WriteData.class).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
        excelWriter.write(list, writeSheet);
        /// 千万别忘记finish 会帮忙关闭流
        excelWriter.finish();*/
        return Result.builder().data(1).build();
    }

    /**
     * 导出文件流
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("export")
    public void export(HttpServletResponse response) throws IOException {
        List<WriteData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WriteData data = new WriteData(i, new Date(), 2, "18330217407");
            list.add(data);
        }

        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileNameNew = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileNameNew);
        EasyExcel.write(response.getOutputStream(), WriteData.class).sheet("模板").doWrite(list);
    }

    /**
     * 导出文件流- 动态修改表头内容
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("exportDynamic")
    public void exportDynamic(HttpServletResponse response) throws IOException {
        List<WriteData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WriteData data = new WriteData(i, new Date(), 2, "18330217407");
            list.add(data);
        }

        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileNameNew = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileNameNew);
        Map<String, String> keys = new HashMap<>();
        keys.put("name", "英文姓名");//对应WriteData类的name字段
        Class<WriteData> writeDataClassNew = EasyExcelFiledUtil.getClassNew(new WriteData(), keys);
        EasyExcel.write(response.getOutputStream(), writeDataClassNew).sheet("模板").doWrite(list);
//        EasyExcel.write(response.getOutputStream(), WriteData.class).sheet("模板").doWrite(list);
    }

    /**
     * 写文件到云服务
     *
     * @throws IOException
     */
    @GetMapping("writePath")
    public void writePath() throws IOException {
        List<WriteData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WriteData data = new WriteData(i, new Date(), 2, "18330217407");
            list.add(data);
        }

        String fileName = System.currentTimeMillis() + ".xlsx";
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        EasyExcel.write(outputStream, WriteData.class).sheet("demo").doWrite(list);
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        //调用文件服务器方法
    }


    /**
     * 写文件到指定路径
     *
     * @throws IOException
     */
    @GetMapping("writePathToLocal1")
    public void writePathToLocal1() throws IOException {
        List<WriteData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WriteData data = new WriteData(i, new Date(), 2, "18330217407");
            list.add(data);
        }
        //定义文件名
        String fileName = "123.xlsx";
        //定义文件路径
        String filePath = "/usr/local/demo/";
        //创建Excel文件
        File file = new File(filePath + fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        boolean newFile = file.createNewFile();
        //方式一 写file
        EasyExcel.write(file).sheet("sheet1").doWrite(list);

        //方式二 写filePath
        EasyExcel.write(filePath + fileName).sheet("sheet1").doWrite(list);
    }

    /**
     * 多个sheets 导出文件流
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("writeSheets")
    public void writeSheets(HttpServletResponse response) throws IOException {
        List<WriteData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WriteData data = new WriteData(i, new Date(), 2 * i, "18330217407");
            list.add(data);
        }
        List<Write2Data> list2 = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Write2Data data = new Write2Data(i * 3, "大内密探排名" + i);
            list2.add(data);
        }
        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileNameNew = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileNameNew);
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
        WriteSheet test1 = EasyExcel.writerSheet(0, "test1").head(WriteData.class).build();
        WriteSheet test2 = EasyExcel.writerSheet(1, "test2").head(Write2Data.class).build();
        excelWriter.write(list, test1).write(list2, test2);
        excelWriter.finish();

    }

    @PostMapping("read1")
    @ResponseBody
    public String read1(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), ReadData.class, new UploadDataListener(uploadService)).sheet().doRead();
        return "success";
    }


    @Autowired
    private Map<String, ExcelHeadValidHandler> excelHandlerMap;


    /**
     * 抽出公共方法1
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("read2")
    @ResponseBody
    public String read2(MultipartFile file) throws IOException {
        List<ReadData> readData = EasyExcelUtil.readExcel(file.getInputStream(), ReadData.class, 0, 1, true);
        return "success";
    }

    /**
     * 抽出公共方法2 -更加抽象
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("read3")
    @ResponseBody
    public String read3(MultipartFile file) throws IOException {
        ExcelHeadValidHandler excelHeadValidHandler = excelHandlerMap.get(ExcelEnum.getNameDesc("1"));
        List<ExcelReadVO> readData = EasyExcelUtil2.readExcel(file.getInputStream(), ExcelReadVO.class, 0, 2, excelHeadValidHandler);
        return "success";
    }

}